home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14622 < prev    next >
Encoding:
Text File  |  1996-08-05  |  2.8 KB  |  133 lines

  1. Path: svnews.ubinet.ubs.com!ubszh!ian.johnston@ubs.com
  2. From: ian.johnston@ubs.com (Ian Johnston (by ubsswop))
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Urgent help - pointers to functions
  5. Date: 1 Apr 1996 11:05:31 GMT
  6. Organization: UBS
  7. Distribution: world
  8. Message-ID: <4jod9r$ka@ubszh.fh.zh.ubs.com>
  9. References: <internews46B6FAA4E6@argonet.co.uk>
  10. NNTP-Posting-Host: nol2179.fh.zh.ubs.com
  11.  
  12. In article <internews46B6FAA4E6@argonet.co.uk>, Charlotte Tomlinson <eeyore@argonet.co.uk> writes:
  13. |> I have implemented a template doubly linked list, the backbones of which
  14. |> is as follows:
  15. |> 
  16.  
  17. [...]
  18.  
  19. |> Then I have a class, called fuzzyset, which uses this dll as a container
  20. |> for fuzzyel instances:
  21. |> 
  22. |> //fuzzyset.h
  23. |> /*snip*/
  24. |> 
  25. |> class fuzzyset {
  26. |>         private:
  27. |>         dllist<fuzzyel> members;
  28. |> 
  29. |>         public:
  30. |>         fuzzyset() {}
  31. |>         fuzzyset(const fuzzyset&);
  32. |>         fuzzyset(const fuzzyel&);
  33. |> /*other functions and operators*/
  34. |> };
  35. |> 
  36. |> 
  37. |> What I would like to do is, within dllist, to implement a function forEach
  38. |> that take a pointer to a function as one argument, and somehow the rest of
  39. |> the arguments required by that function, and carries that function out
  40. |> over each element of the list. 
  41. |> 
  42. |> One example of what I need to do is as follows.  In my main program (where
  43. |> fuzzyset is included), I need to be able to call a function that prints
  44. |> every element of the 'members' list in any called instance of a fuzzyset.
  45. |> 
  46. |> I need the forEach function to be quite generic, because I will have other
  47. |> uses for it later.
  48.  
  49. It's probably best here to use a "function object", that is, an object
  50. which represents a function.
  51.  
  52. For example:
  53.  
  54. template <class T>
  55. struct Function
  56. {
  57.     virtual void operator ()(T const &item) const = 0;
  58. };
  59.  
  60.  
  61. template <class T>
  62. void dllist<T>::forEach(Function<T> const &func)
  63. {
  64.    node<T> *node;
  65.  
  66.    for (node = head; node != 0; node = node->getnext())
  67.     func(node->getinfo());
  68. }
  69.  
  70.  
  71. Now you can create derived classes of Function to do specific things:
  72.  
  73.  
  74. template <class T>
  75. struct ItemPrinter : public Function<T>
  76. {
  77.     virtual void operator()(T const &item) const
  78.     {
  79.     cout << item << endl;
  80.     }
  81. };
  82.  
  83.  
  84.  
  85. // Somewhere in fuzzyset:
  86.  
  87.    ItemPrinter<fuzzyel> printer;
  88.    members.forEach(printer);
  89.  
  90.  
  91. Or, even more compactly (and this is why the operator () is const):
  92.  
  93.   members.forEach(ItemPrinter<fuzzyel>());
  94.  
  95.  
  96.  
  97. Your derived class of Function can include data members as, effectively,
  98. extra parameters you would have passed to the forEach function.
  99.  
  100. For example, to change each item:
  101.  
  102.  
  103. template <class T>
  104. struct Changer : public Function<T>
  105. {
  106.     Changer(T const &item)
  107.         : value(item)
  108.     {
  109.     }
  110.  
  111.     virtual void operator ()(T const &item) const
  112.     {
  113.     item = value;
  114.     }
  115.  
  116.     T const &value;
  117. };
  118.  
  119.  
  120.  
  121. fuzzyel new_value;
  122. Changer func(new_value);
  123.  
  124. members.forEach(func);
  125.  
  126.  
  127. Ian
  128.  
  129.  
  130.  
  131.  
  132.  
  133.